package com.erp.gather.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.erp.gather.domain.ErpCollectProductCategory;
import com.erp.gather.domain.ErpProductAutoTestStore;
import com.erp.gather.domain.bo.ErpCollectProductCategoryBo;
import com.erp.gather.domain.dto.ErpCollectProductCategoryDto;
import com.erp.gather.domain.vo.ErpCollectProductCategoryVo;
import com.erp.gather.mapper.ErpCollectProductCategoryMapper;
import com.erp.gather.mapper.ErpCollectProductMapper;
import com.erp.gather.mapper.ErpProductAutoTestStoreMapper;
import com.erp.gather.service.IErpCollectProductCategoryService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.oldUtils.StringUtils;
import com.ruoyi.common.redis.utils.RedisUtils;
import com.ruoyi.gather.api.domain.ErpCollectProduct;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 采集商品类目Service业务层处理
 *
 * @author erp
 * @date 2023-03-22
 */
@RequiredArgsConstructor
@Service
public class ErpCollectProductCategoryServiceImpl implements IErpCollectProductCategoryService {
    String KEY = "ERP_COLLECT_PRODUCT_CATEGORY";
    String ALREADY_KEY = "ERP_COLLECT_PRODUCT_CATEGORY_ALREADY";

    private final ErpCollectProductCategoryMapper baseMapper;
    private final ErpProductAutoTestStoreMapper erpProductAutoTestStoreMapper;
    private final ErpCollectProductMapper erpCollectProductMapper;

    @Override
    public List<ErpCollectProductCategory> selectTopList() {
        Long parentId = 0L;
        List<ErpCollectProductCategory> erpCollectProductCategories = baseMapper.selectList(
                new LambdaQueryWrapper<ErpCollectProductCategory>().eq(ErpCollectProductCategory::getParentId, parentId)
                        .eq(ErpCollectProductCategory::getStatus, 0));
        return erpCollectProductCategories;
    }

    @Override
    public List<Object> selectList(ErpCollectProductCategoryBo bo) {
        // 获取缓存
        List<Object> list = RedisUtils.getCacheObject(KEY);
        System.out.println(list);
        if (list != null && list.size() > 0) {
            return list;
        }
        list = loadingCache();
        return list;
    }

    private List<Object> loadingCache() {
        ErpCollectProductCategoryBo bo = new ErpCollectProductCategoryBo();
        bo.setStatus(0);
        List<ErpCollectProductCategoryVo> queryList = queryList(bo);
        List<Object> list = new ArrayList<>();
        for (ErpCollectProductCategoryVo vo : queryList) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", vo.getName());
            map.put("id", vo.getId());
            map.put("isleaf", vo.getIsleaf());
            map.put("parentId", vo.getParentId());
            list.add(map);
        }
        RedisUtils.setCacheObject(KEY, list);
        return list;
    }

    /**
     * 查询采集商品类目列表
     */
    @Override
    public List<ErpCollectProductCategoryVo> queryList(ErpCollectProductCategoryBo bo) {
        LambdaQueryWrapper<ErpCollectProductCategory> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public ErpCollectProductCategoryVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    @Override
    public Boolean insertByBo(ErpCollectProductCategoryBo bo) {
        ErpCollectProductCategory add = BeanUtil.toBean(bo, ErpCollectProductCategory.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    @Override
    public Boolean updateByBo(ErpCollectProductCategoryBo bo) {
        ErpCollectProductCategory update = BeanUtil.toBean(bo, ErpCollectProductCategory.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    @Override
    public Boolean deleteWithValidByIds(List<Long> ids, boolean isValid) {
        if (isValid) {
            // TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<Object> selectAlreadyList() {
        List<Object> resList = RedisUtils.getCacheObject(ALREADY_KEY);
        if (resList != null && resList.size() > 0) {
            return resList;
        } else {

            // 获取已经有商品的叶子类目
            LambdaQueryWrapper<ErpCollectProduct> lqw = Wrappers.lambdaQuery();
            lqw.isNotNull(ErpCollectProduct::getCategoryId);
            lqw.groupBy(ErpCollectProduct::getCategoryId);
            List<ErpCollectProduct> proList = erpCollectProductMapper.selectList(lqw);
            List<Long> collect = proList.stream().map(pro -> pro.getCategoryId()).collect(Collectors.toList());

            if (collect.size() > 0) {
                List<ErpCollectProductCategory> categoryList = baseMapper.selectBatchIds(collect);
                Map<String, String> map = new HashMap<>();
                categoryList.forEach(category -> {
                    List<String> asList = Arrays.asList(category.getAncestors().split(","));
                    for (String str : asList) {
                        map.put(str, str);
                    }
                });

                // 查询
                List<ErpCollectProductCategory> parents = baseMapper
                        .selectBatchIds(new ArrayList<String>(map.values()));
                categoryList.addAll(parents);

                resList = new ArrayList<Object>();
                for (ErpCollectProductCategory vo : categoryList) {
                    Map<String, Object> map1 = new HashMap<>();
                    map1.put("name", vo.getName());
                    map1.put("id", vo.getId());
                    map1.put("isleaf", vo.getIsleaf());
                    map1.put("parentId", vo.getParentId());
                    resList.add(map1);
                }
                //TODO 之前设置的是十分钟，现在取消了时间限制，需要验证是否有问题
                RedisUtils.setCacheObject(ALREADY_KEY, resList);

                return resList;
            }
        }

        return null;
    }

    @Override
    public List<ErpCollectProductCategoryDto> selectStatisticsList(String categoryName, Long brandId) {

        List<Map<String, Object>> selectStatisticsList = baseMapper.selectStatisticsList(categoryName, brandId);

        Map<String, String> parentMapIds = new HashMap<>();
        Map<Long, ErpCollectProductCategoryDto> cateMap = new HashMap<>();
        for (Map<String, Object> map : selectStatisticsList) {

            String ancestors = (String) map.get("ancestors");
            if (Objects.isNull(ancestors)) {
                continue;
            }
            List<String> asList = Arrays.asList(ancestors.split(","));
            for (String str : asList) {
                parentMapIds.put(str, str);
            }

            Long categoryId = (Long) map.get("categoryId");
            if (cateMap.containsKey(categoryId)) { // 包含这个key，那就判断品牌有没有

                String brandName = (String) map.get("brandName");
                Long coun = (Long) map.get("coun");

                ErpCollectProductCategoryDto dto = cateMap.get(categoryId);

                Long proNumber = dto.getProNumber();
                proNumber += coun;
                dto.setProNumber(proNumber);

                Map<String, Long> brand = (Map<String, Long>) dto.getBrand();
                if (brand.containsKey(brandName)) {
                    Long long1 = brand.get(brandName);
                    long1 += coun;
                    brand.put(brandName, long1);
                } else {
                    brand.put(brandName, coun);
                }

            } else { // 不包含，就直接放
                ErpCollectProductCategoryDto dto = new ErpCollectProductCategoryDto();
                dto.setName(map.get("name"));
                dto.setId(categoryId);
                dto.setIsleaf(map.get("isleaf"));
                dto.setParentId((Long) map.get("parentId"));
                dto.setAncestors(ancestors);

                Long coun = (Long) map.get("coun");
                dto.setProNumber(coun);

                Map<String, Long> map2 = new HashMap<>();
                map2.put((String) map.get("brandName"), coun);
                dto.setBrand(map2);

                cateMap.put(categoryId, dto);
            }
        }

        // 获取祖籍集合
        List<ErpCollectProductCategory> parents = new ArrayList<>();
        if (parentMapIds.size() > 0)
            parents = baseMapper.selectBatchIds(parentMapIds.keySet());
        Map<Long, ErpCollectProductCategoryDto> parentMap = new HashMap<>();
        for (ErpCollectProductCategory erpCollectProductCategory : parents) {

            Long categoryId = erpCollectProductCategory.getId();

            ErpCollectProductCategoryDto dto = new ErpCollectProductCategoryDto();
            dto.setName(erpCollectProductCategory.getName());
            dto.setId(categoryId);
            dto.setIsleaf(erpCollectProductCategory.getIsleaf());
            dto.setParentId(erpCollectProductCategory.getParentId());
            dto.setAncestors(erpCollectProductCategory.getAncestors());

            dto.setProNumber(0l);

            Map<String, Long> map2 = new HashMap<>();
            dto.setBrand(map2);

            parentMap.put(categoryId, dto);
        }

        ArrayList<ErpCollectProductCategoryDto> resList = new ArrayList<>(cateMap.values());

        // 计算祖籍的品牌的个数
        for (ErpCollectProductCategoryDto dto : resList) {
            Long parentId = dto.getParentId();

            ErpCollectProductCategoryDto targetDto = parentMap.get(parentId);
            if (targetDto != null)
                statistics(dto, targetDto, parentMap);
        }

        ArrayList<ErpCollectProductCategoryDto> resList1 = new ArrayList<>(parentMap.values());
        resList.addAll(resList1);

        // 排序
        resList.sort(Comparator.comparing((ErpCollectProductCategoryDto::getProNumber)).reversed());

        return resList;
    }

    @Override
    public List<ErpCollectProductCategory> querySubordinateCategory(String categoryId) {
        return baseMapper.selectList(
                new LambdaQueryWrapper<ErpCollectProductCategory>()
                        .eq(ErpCollectProductCategory::getParentId, categoryId)
        );
    }

    @Override
    public R<Object> createPrimaryCategory() {
        List<ErpCollectProductCategory> categoryList = baseMapper.selectList();
        for (ErpCollectProductCategory category : categoryList) {
            String ancestors = category.getAncestors();
            List<String> list = Arrays.asList(ancestors.split(","));
            if (list.size() > 1) {
                category.setPrimaryCategory(Long.valueOf(list.get(1)));
                System.out.println(list.get(1));
                baseMapper.updateById(category);
            }

        }
        return null;
    }

    public void statistics(ErpCollectProductCategoryDto sourceDto, ErpCollectProductCategoryDto targetDto,
                           Map<Long, ErpCollectProductCategoryDto> parentMap) {

        Long sourceProNumber = sourceDto.getProNumber();

        Long targetProNumber = targetDto.getProNumber();
        targetProNumber += sourceProNumber;
        targetDto.setProNumber(targetProNumber);

        Map<String, Long> sourceMapBrand = sourceDto.getBrand();

        Map<String, Long> targetBrand = targetDto.getBrand();
        for (String key : sourceMapBrand.keySet()) {
            if (targetBrand.containsKey(key)) {
                Long long1 = targetBrand.get(key);
                long1 += sourceMapBrand.get(key);
                targetBrand.put(key, long1);
            } else {
                targetBrand.put(key, sourceMapBrand.get(key));
            }
        }

        // 递归
        Long parentId = targetDto.getParentId();
        if (!parentId.equals(0l)) {
            ErpCollectProductCategoryDto targetDto1 = parentMap.get(parentId);
            if (targetDto1 != null)
                statistics(sourceDto, targetDto1, parentMap);
        }
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ErpCollectProductCategory entity) {
        // TODO 做一些数据校验,如唯一约束
    }

    private LambdaQueryWrapper<ErpCollectProductCategory> buildQueryWrapper(ErpCollectProductCategoryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ErpCollectProductCategory> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getName()), ErpCollectProductCategory::getName, bo.getName());
        lqw.eq(bo.getStatus() != null, ErpCollectProductCategory::getStatus, bo.getStatus());
        lqw.eq(bo.getParentId() != null, ErpCollectProductCategory::getParentId, bo.getParentId());
        lqw.eq(StringUtils.isNotBlank(bo.getRevision()), ErpCollectProductCategory::getRevision, bo.getRevision());
        return lqw;
    }

    @Override
    public Boolean judgeIsBottomLevel(Long categoryId) {
        if (categoryId == null)
            return false;
        ErpCollectProductCategory erpCollectProductCategory = baseMapper.selectById(categoryId);
        if (erpCollectProductCategory == null)
            return false;
        return erpCollectProductCategory.getIsleaf();

    }

    @Override
    public List<ErpCollectProductCategory> getCategoryList(List<String> category) {
        return baseMapper.selectList(
                new LambdaQueryWrapper<ErpCollectProductCategory>()
                        .in(ErpCollectProductCategory::getId, category)
        );
    }

    @Override
    public List<Long> getCategoryTreeListForStore(Long categoryId) {
        try {
            Long topCategoryId = null;
            // 获取商品类目的顶级类目
            ErpCollectProductCategory erpCollectProductCategory = baseMapper
                    .selectOne(new LambdaQueryWrapper<ErpCollectProductCategory>().eq(ErpCollectProductCategory::getId,
                            categoryId));
            if (erpCollectProductCategory.getParentId() == 0) {
                // 顶点
                topCategoryId = erpCollectProductCategory.getId();
            } else {
                // 非顶点
                // 转为数组，获取第数组的第二个对象
                String[] ancestors = erpCollectProductCategory.getAncestors().split(",");
                topCategoryId = Long.valueOf(ancestors[1]);
            }

            // 获取表内有权限的店铺
            LambdaQueryWrapper<ErpProductAutoTestStore> lqw = new LambdaQueryWrapper<ErpProductAutoTestStore>();
            lqw.eq(ErpProductAutoTestStore::getStatus, 1);
            lqw.eq(ErpProductAutoTestStore::getCategoryId, topCategoryId);
//            lqw.last("limit 1");
            List<ErpProductAutoTestStore> storeList = erpProductAutoTestStoreMapper.selectList(lqw);
            if (storeList != null && storeList.size() > 0) {
                return storeList.stream().map(e -> e.getSellerStoreEmpowerId()).collect(Collectors.toList());
            } else {
                return null;
            }
        } catch (Exception e) {
            // 获取类目异常
            return null;
        }
    }

    /**
     * @Description: 根据类目名称，模糊查询类目ID集合
     * @Author: j.zh
     * @Date: 2024/6/9
     * @param categoryName
     * @return
     * @Version: 4.0.0
     **/
    public List<Long> getCategoryIdListByCategoryName(String categoryName){
        List<ErpCollectProductCategory> collectProductCategoryList = baseMapper.selectList(new LambdaQueryWrapper<ErpCollectProductCategory>()
                .like(ErpCollectProductCategory::getName, "%" + categoryName + "%"));
        if (collectProductCategoryList != null){
            return collectProductCategoryList.stream()
                    .map(e -> e.getId()).collect(Collectors.toList());
        }
        return null;
    }


}
